﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace BoAddonBiz_FreightForwarder.ObjectFind
{
    enum WhereValue { left, right, all, no }
    class ObjectFindLines : List<ObjectFindLine>
    {
        private string _ObjectType;
        private string _SQL;
        private string _WhereSQL;
        private string _FieldsSQL;
        private string _TableSQL;
        private Displayfields _fields;
        private Displayfield _field;
        private tables _tables;
        private table _table;
        private wherefields _Wherefields;
        private wherefield _Wherefield;

        public string ObjectType
        {
            get { return _ObjectType; }
            set { _ObjectType = value; }
        }

        public string WhereSQL
        {
            get
            {
                _WhereSQL = "";
                foreach (wherefield ofield in _Wherefields)
                {
                    _WhereSQL = string.IsNullOrEmpty(_WhereSQL) ? "" : _WhereSQL + " And ";
                    string FieldName = ofield.table + "." + ofield.field;
                    string FieldFValue = string.Empty;
                    string FieldTValue = string.Empty;
                    if (string.IsNullOrEmpty(ofield.FValue))
                    {
                        FieldFValue = "{" + FieldName + "}";
                    }
                    else
                        FieldFValue = ofield.FValue;
                    if (string.IsNullOrEmpty(ofield.TValue))
                    {
                        FieldTValue = "{" + FieldName + "}";
                    }
                    else
                        FieldTValue = ofield.TValue;

                    switch (ofield.DataType)
                    {
                        case FieldDataType.Int:
                            switch (ofield.DeleteValue)
                            {
                                case WhereValue.left:
                                    _WhereSQL += " ( " + FieldName + " <= " + FieldTValue + " ) ";
                                    break;
                                case WhereValue.right:
                                    _WhereSQL += " ( " + FieldName + " >= " + FieldFValue + " ) ";
                                    break;
                                case WhereValue.all:
                                    if (_WhereSQL.EndsWith(" And "))
                                        _WhereSQL = _WhereSQL.Substring(0, _WhereSQL.Length - " And ".Length);
                                    break;
                                default:
                                    if (Convert.ToDecimal(FieldTValue) > 0) /*如果为0则不作为条件 by WangPeng 2012年8月7日 13:37:24*/
                                    {
                                        _WhereSQL += " ( " + FieldName + " >= " + FieldFValue + "  And " + FieldName + " <= " + FieldTValue + " ) ";
                                    }
                                    else
                                    {
                                        if (_WhereSQL.Length > 5)
                                        {
                                            _WhereSQL = _WhereSQL.Remove(_WhereSQL.Length - " And ".Length);
                                        }
                                    }
                                    break;
                            }
                            break;
                        case FieldDataType.DateTime:
                            switch (ofield.DeleteValue)
                            {
                                case WhereValue.left:
                                    _WhereSQL += " ( " + FieldName + " <= '" + FieldTValue + "' ) ";
                                    break;
                                case WhereValue.right:
                                    _WhereSQL += " ( " + FieldName + " >= '" + FieldFValue + "' ) ";
                                    break;
                                case WhereValue.all:
                                    if (_WhereSQL.EndsWith(" And "))
                                        _WhereSQL = _WhereSQL.Substring(0, _WhereSQL.Length - " And ".Length);
                                    break;
                                default:
                                    _WhereSQL += " ( " + FieldName + " >= '" + FieldFValue + "' And " + FieldName + " <= '" + FieldTValue + "' ) ";
                                    break;
                            }
                            break;
                        case FieldDataType.String:
                            switch (ofield.DeleteValue)
                            {
                                case WhereValue.left:
                                    if (_WhereSQL.EndsWith(" And "))
                                        _WhereSQL = _WhereSQL.Substring(0, _WhereSQL.Length - " And ".Length);
                                    break;
                                default:
                                    _WhereSQL += " ( " + FieldName + " Like '%" + FieldFValue + "%' ) ";
                                    break;
                            }
                            break;
                        case FieldDataType.Enum:
                            switch (ofield.DeleteValue)
                            {
                                case WhereValue.left:
                                    if (_WhereSQL.EndsWith(" And "))
                                        _WhereSQL = _WhereSQL.Substring(0, _WhereSQL.Length - " And ".Length);
                                    break;
                                default:
                                    _WhereSQL += " ( " + FieldName + " = '" + FieldFValue + "' ) ";
                                    break;
                            }
                            break;

                    }
                }
                return _WhereSQL;
            }
        }
        public string FieldsSQL
        {
            get
            {
                _FieldsSQL = "";
                foreach (Displayfield ofield in _fields)
                {

                    if (ofield.field.ToUpper() == ofield.table.ToString() + ".DocEntry".ToUpper())
                        continue;
                    _FieldsSQL = string.IsNullOrEmpty(_FieldsSQL) ? "" : _FieldsSQL + ",";
                    _FieldsSQL += ofield.field + " " + ofield.fieldName;
                }

                return _FieldsSQL;
            }
        }
        public string TableSQL
        {
            get
            {
                _TableSQL = "";
                if (_tables != null)
                {
                    _TableSQL = _tables.GetMasterTable().TableName;
                    foreach (table otable in _tables)
                    {
                        if (!otable.Master)
                        {
                            _TableSQL += " LEFT JOIN " + otable.TableName + " ON ";
                            table mastertable = _tables.GetMasterTable();

                            _TableSQL += mastertable.PrimaryKey + " = " + otable.PrimaryKey;
                        }
                    }
                }
                return _TableSQL;
            }
        }
        public string SQL
        {
            get
            {
                table master = _tables.GetMasterTable();
                if (master != null)
                {
                    _SQL = "SELECT " + "N'" + ObjectType + "' Object," /*master.TableName + ".Object,"*/ + master.TableName + ".DocEntry,";
                }
                else
                {
                    _SQL = "SELECT '' Object," + _tables[0].TableName + ".DocEntry,";
                }
                if (WhereSQL.Trim() == "")
                {
                    _SQL += FieldsSQL;
                    if (_SQL.EndsWith(","))
                        _SQL = _SQL.Substring(0, _SQL.Length - 1);
                    _SQL += " FROM " + TableSQL + Authioity();
                }
                else
                {
                    _SQL += FieldsSQL;
                    if (_SQL.EndsWith(","))
                        _SQL = _SQL.Substring(0, _SQL.Length - 1);
                    _SQL += " FROM " + TableSQL + Authioity() + " And " + WhereSQL;
                }
                _SQL = _SQL + " Order By " + Tables.GetMasterTable().TableName + ".DocEntry Asc";
                return _SQL;
            }
        }
        /// <summary>
        /// 数据所有权限
        /// </summary>
        /// <returns></returns>
        private string Authioity()
        {
            if (Utils.IsManager()) return " WHERE 1=1 ";
            string SQL = string.Empty;
            string UserIDString = string.Empty;
            table MasterTable = Tables.GetMasterTable();
            //判断查询对象是否是开票的数据，如果是则不受权限控制
            if (MasterTable.TableName == "[@AVA_OOIR]" || MasterTable.TableName == "[@AVA_OOIP]")
            {
                if (Utils.IsFinanceUserID())
                {
                    foreach (int UserID in Utils.GetFinanceID())
                    {
                        UserIDString += UserID.ToString() + ",";
                    }
                    if (!string.IsNullOrEmpty(UserIDString))
                        UserIDString = UserIDString.Substring(0, UserIDString.Length - 1);
                    else
                        UserIDString = "-2";
                    SQL = " WHERE " + MasterTable.TableName + ".UserSign IN (" + UserIDString + ")";
                    return SQL;
                }
            }
            foreach (int UserID in Utils.GetPersons())
            {
                UserIDString += UserID.ToString() + ",";
            }
            if (!string.IsNullOrEmpty(UserIDString))
                UserIDString = UserIDString.Substring(0, UserIDString.Length - 1);
            else
                UserIDString = "-2";
            SQL = " WHERE " + MasterTable.TableName + ".UserSign IN (" + UserIDString + ")";
            return SQL;
        }
        public Displayfields fields
        {
            get { return _fields; }
        }
        public tables Tables
        {
            get { return _tables; }
        }
        public wherefields Wherefields
        {
            get { return _Wherefields; }
        }
        #region constructor
        public ObjectFindLines()
        {
            _fields = new Displayfields();
            _tables = new tables();
            _Wherefields = new wherefields();
        }
        #endregion
        #region public methods
        public ObjectFindLine Add()
        {
            ObjectFindLine oLine = new ObjectFindLine();
            oLine.PropertyChanging += new System.ComponentModel.PropertyChangingEventHandler(oLine_PropertyChanging);
            oLine.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(oLine_PropertyChanged);
            this.Add(oLine);
            return oLine;
        }
        #endregion
        #region private methods
        void oLine_PropertyChanging(object sender, System.ComponentModel.PropertyChangingEventArgs e)
        {
            string FieldName = string.Empty;
            ObjectFindLine FindLine = (sender as ObjectFindLine);
            FieldName = FindLine.TableName + "." + FindLine.Field;
            #region fields
            if (FindLine.IsDisplay)
            {
                if (_fields.Exists(FieldName))
                {
                    _fields.Remove(FieldName);
                }
            }
            #endregion
            #region table
            if (FindLine.IsFind || FindLine.IsDisplay)
            {
                if (_tables.Exists(FindLine.TableName))
                {
                    if (_fields.ExistsTable(FindLine.TableName) == false && _Wherefields.ExistsTable(FindLine.TableName) == false)
                    {
                        _tables.Remove(FindLine.TableName);
                    }
                }
            }
            #endregion
            #region Where
            if (FindLine.IsFind)
            {
                if (_Wherefields.Exists(FindLine.TableName, FindLine.Field))
                {
                    _Wherefields.Remove(FindLine.TableName, FindLine.Field);
                }
            }
            #endregion
        }
        void oLine_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            ObjectFindLine FindLine = (sender as ObjectFindLine);
            #region WhereSQL
            if (FindLine.IsFind)
            {
                if (_Wherefields.Exists(FindLine.TableName, FindLine.Field)) return;
                _Wherefield = _Wherefields.Add();
                _Wherefield.table = FindLine.TableName;
                _Wherefield.field = FindLine.Field;
                _Wherefield.DataType = FindLine.DataType;
                _Wherefield.alias = FindLine.FieldName;
                _Wherefield.size = FindLine.SizeId;
                _Wherefield.alternates = FindLine.Alternates;

                switch (FindLine.DataType)
                {
                    case FieldDataType.Int:
                        _Wherefield.count = 2;
                        break;
                    case FieldDataType.DateTime:
                        _Wherefield.count = 2;
                        break;
                    case FieldDataType.String:
                        _Wherefield.count = 1;
                        break;
                    case FieldDataType.Enum:
                        _Wherefield.count = 1;
                        break;
                }
            }
            #endregion
            #region Display
            if (FindLine.IsDisplay)
            {
                _field = _fields.Add();
                _field.table = FindLine.TableName;
                _field.field = FindLine.TableName + "." + FindLine.Field;
                _field.fieldName = string.Format("[{0}]", FindLine.FieldName);
            }
            #endregion
            #region TableSQL
            if (FindLine.IsDisplay || FindLine.IsFind)
            {
                if (!_tables.Exists(FindLine.TableName))
                {
                    if (FindLine.Master)
                    {
                        _table = _tables.Add();
                        _table.TableName = FindLine.TableName;
                        _table.PrimaryKey = _table.TableName + ".DocEntry";
                        _table.Master = true;
                    }
                    else
                    {
                        _table = _tables.Add();
                        _table.TableName = FindLine.TableName;
                        _table.PrimaryKey = _table.TableName + ".DocEntry";
                        _table.Master = false;
                    }
                }
            }
            #endregion
        }
        #endregion
        #region Table
        internal class table
        {
            public string TableName { set; get; }
            public string PrimaryKey { set; get; }
            public bool Master { set; get; }
        }
        internal class tables : List<table>
        {
            public table Add()
            {
                table otable = new table();
                this.Add(otable);
                return otable;
            }
            public bool Exists(string TableName)
            {
                foreach (table otable in this)
                {
                    if (otable.TableName == TableName)
                        return true;
                }
                return false;
            }
            public bool Remove(string TableName)
            {
                foreach (table otable in this)
                {
                    if (otable.TableName == TableName)
                    {
                        this.Remove(otable);
                        return true;
                    }
                }
                return false;
            }
            public table GetMasterTable()
            {
                foreach (table otable in this)
                {
                    if (otable.Master)
                        return otable;
                }
                return null;
            }
        }
        #endregion
        #region Where条件
        internal class wherefield
        {
            internal string _Key;

            public string Key
            {
                get
                {
                    return _Key;
                }
            }
            public string table;//表名
            public string field;//字段 DocEntry
            public FieldDataType DataType;
            public int size;
            public FieldAlternates alternates;
            public string alias;//名称 单据号
            public int count;//查找字段的个数
            public string FValue;
            public string TValue;
            public WhereValue DeleteValue = WhereValue.no;
        }
        internal class wherefields : List<wherefield>
        {
            private int count = 0;

            public wherefield Add()
            {
                wherefield ofield = new wherefield();
                ofield._Key = count.ToString();
                count++;
                this.Add(ofield);
                return ofield;
            }
            public bool Exists(string TableName, string Field)
            {
                foreach (wherefield field in this)
                {
                    if (field.table == TableName && field.field == Field)
                        return true;
                }
                return false;
            }
            public bool ExistsTable(string TableName)
            {
                foreach (wherefield field in this)
                {
                    if (field.table == TableName)
                        return true;
                }
                return false;
            }
            public bool Remove(string TableName, string Field)
            {
                foreach (wherefield field in this)
                {
                    if (field.table == TableName && field.field == Field)
                    {
                        this.Remove(field);
                        return true;
                    }
                }
                return false;
            }
            public wherefield Getfield(string key)
            {
                foreach (wherefield field in this)
                {
                    if (field.Key == key)
                        return field;
                }
                return null;
            }
            public bool Remove(string key, WhereValue DeleteValue)
            {
                foreach (wherefield field in this)
                {
                    if (field.Key == key)
                    {
                        field.DeleteValue = DeleteValue;
                        return true;
                    }
                }
                return false;
            }
        }
        #endregion
        #region 显示字段
        internal class Displayfield
        {
            public string table;
            public string field;
            public string fieldName;
        }
        internal class Displayfields : List<Displayfield>
        {
            public Displayfield Add()
            {
                Displayfield ofield = new Displayfield();
                this.Add(ofield);
                return ofield;
            }
            public bool Exists(string Field)
            {
                foreach (Displayfield field in this)
                {
                    if (field.field == Field)
                        return true;
                }
                return false;
            }
            public bool ExistsTable(string TableName)
            {
                foreach (Displayfield field in this)
                {
                    if (field.table == TableName)
                        return true;
                }
                return false;
            }
            public bool Remove(string Field)
            {
                foreach (Displayfield field in this)
                {
                    if (field.field == Field)
                    {
                        this.Remove(field);
                        return true;
                    }
                }
                return false;
            }
        }
        #endregion
    }
}
